深度学习算法(第28期)----如何高效的训练自编码器?
上期我们一起学习了深度学习中的栈式自编码器的相关知识,
深度学习算法(第27期)----栈式自编码器
今天我们一起学一下如何高效的训练自编码器。
多图训练
上期我们学过在tensorflow中如何实现一个栈式自编码器,当然那样的自编码器训练起来注定是很慢的。那么通常的做法是一次训练一个浅浅的自编码器,然后堆到一起成为一个栈式自编码器,这在训练一些比较深的自编码器的时候十分有用,如下图:
在训练的第一阶段,第一个自编码器学习如何重构输入。在训练的第二个阶段,第二个自编码器学习如何重构第一个自编码器的隐藏层。最后,把这两个自编码器堆叠起来。我们可以很容易的用这种方法训练更深的自编码器。
为了实现这种多阶段的训练算法,最简单的方法就是对每一个阶段用不同的图。 训练完一个自编码器后,您只需通过它运行训练集并捕获隐藏层的输出,然后把这个输出作为下一个自编码器的训练集。一旦所有自编码器都以这种方式进行了训练,我们只需要简单的复制每个自编码器的权重和偏置,然后把它们堆叠起来形成深度自编码器。实现这种方法非常简单,所以我们不在这里详细说明。
单图训练
另一种方法是使用包含整个栈式自编码器的单个图,以及执行每个训练阶段的一些额外操作,如下图:
这里需要解释下:
图中的中间列是完整的栈式自编码器。这部分可以在训练后使用。
左边的一系列操作是训练的第一阶段,它创建一个绕过隐藏层2和3的输出层。该输出层与栈式自编码器的输出层共享相同的权重和偏置。该输出层上面是在使之尽可能接近输入的训练操作。因此,该阶段将训练隐藏层1和输出层(即第一自编码器)的权重和偏置。
右边的训练操作相当于是训练的第二个阶段,它旨在使得隐藏层3尽可能的逼近隐藏层1。注意到,在训练第二个阶段的时候,我们必须冻结隐藏层1,这个阶段,我们将训练隐藏层2和隐藏层3的权重和偏置。
代码实现
代码如下:
[...] # Build the whole stacked autoencoder normally.
# In this example, the weights are not tied.
optimizer = tf.train.AdamOptimizer(learning_rate)
with tf.name_scope("phase1"):
phase1_outputs = tf.matmul(hidden1, weights4) + biases4
phase1_reconstruction_loss = tf.reduce_mean(tf.square(phase1_outputs - X))
phase1_reg_loss = regularizer(weights1) + regularizer(weights4)
phase1_loss = phase1_reconstruction_loss + phase1_reg_loss
phase1_training_op = optimizer.minimize(phase1_loss)
with tf.name_scope("phase2"):
phase2_reconstruction_loss = tf.reduce_mean(tf.square(hidden3 - hidden1))
phase2_reg_loss = regularizer(weights2) + regularizer(weights3)
phase2_loss = phase2_reconstruction_loss + phase2_reg_loss
train_vars = [weights2, biases2, weights3, biases3]
phase2_training_op = optimizer.minimize(phase2_loss, var_list=train_vars)
第一阶段相对比较简单:我们只创建一个跳过隐藏层2和3的输出层,然后构建训练操作以最小化输出和输入之间的距离(加上一些正则化)。
第二阶段只是增加了将隐藏层3和隐藏层1的输出之间的距离最小化的操作(包括一些正则化)。更重要的是,我们向minim()方法提供可训练变量的列表,确保省略权重1和偏差1;这有效地冻结了阶段2期间的隐藏层1。
在执行阶段,我们需要做的就是为阶段1做一些迭代进行训练操作,然后阶段2训练运行更多的迭代。
由于隐藏层1在阶段2期间被冻结,所以对于任何给定的训练实例其输出将总是相同的。 为了避免在每个时期重新计算隐藏层1的输出,我们可以在阶段1结束时用整个训练集计算它,然后直接在阶段2中输入隐藏层1的缓存输出。这在性能上可以有所提升。
好了,至此,今天我们简单学习了如何高效的训练栈式自编码器的相关知识,希望有些收获,下期我们将更深一步的学习如何可视化自编码器的相关知识,欢迎留言或进社区共同交流,喜欢的话,就点个“在看”吧,您也可以置顶公众号,第一时间接收最新内容。